home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / COMPILER / SATHER / !Sather / System / Common / h / runtime < prev   
Text File  |  1997-01-16  |  18KB  |  390 lines

  1. /* Routines which are provided in runtime.c */
  2.  
  3. void rt_aset(void *buf, INT bit, BOOL val, INT maxbits);
  4. BOOL rt_aget(void *buf, INT bit, INT maxbits);
  5. FLT rt_flt_aset(FLT f,INT bit,BOOL val);
  6. BOOL rt_flt_aget(FLT f, INT bit);
  7. FLTD rt_fltd_aset(FLTD f, INT bit, BOOL val);
  8. BOOL rt_fltd_aget(FLTD f, INT bit);
  9. void rt_flt_get_rep(FLT f,BOOL* sign,INT* exp,INT* mantissa);
  10. void rt_fltd_get_rep(FLTD f,BOOL* sign,INT* exp,INT* mlo,INT* mhi);
  11. int rt_str_file_open(char *nm);
  12. int rt_str_file_size(int fd);
  13. void rt_str_file_in_str(int fd, char *s, int st, int sz);
  14. void rt_str_file_in_fstr(int fd, char *s, int st, int sz, int bst);
  15. void rt_str_file_close(int fd);
  16. char **rt_create_astr (int size, char *s);
  17. void *rt_alloc(size_t size, INT tag);
  18. void *rt_arr_alloc(size_t size1, INT tag, size_t size2, INT n);
  19. void *rt_alloc_atomic(size_t size, INT tag);
  20. void *rt_arr_alloc_atomic(size_t size1, INT tag, size_t size2, INT n);
  21. void rt_segfault_handler();
  22. int rt_fatal(char *file, int line, char *msg);
  23. int rt_fatal_2(char *file, int line, char *msg, char *str);
  24. int rt_fatal2(char *msg);
  25. int rt_fatal2_2(char *msg, char *str);
  26. void rt_start();
  27. void rt_stop();
  28. /*
  29. int rt_file_open(CHAR *nm);
  30. int rt_file_size(INT fd);
  31. void rt_file_in_str(INT fd, CHAR *s, INT st, INT sz);
  32. void rt_file_in_fstr(INT fd, CHAR *s, INT st, INT sz, INT bst);
  33. void rt_file_close(INT fd);
  34. */
  35.  
  36. #ifdef DEBUG
  37. #define S_DEBUG
  38. #endif
  39.  
  40. #ifdef STATS
  41. # ifndef RUNTIME
  42.    extern int rt_dispatches;
  43. # endif
  44. # define COUNT_DISPATCH rt_dispatches++
  45. #endif
  46.  
  47. /* It's okay to replicate arguments in macros here - the compiler
  48.  * always makes temporary locals for anything that might be a macro.
  49. */
  50.  
  51. #ifdef PRINT_BACKTRACE
  52. # ifdef DEBUG
  53.    int rt_fatal_po(char *,int,char *,struct _func_frame *);
  54.    int rt_fatal_p2_o(char *,int,char *,char *,struct _func_frame *);
  55. #  define FATAL(msg)     rt_fatal_po(__FILE__,__LINE__,msg,&FF)
  56. #  define FATAL2(msg,str) rt_fatal_2_po(__FILE__,__LINE__,msg,str,&FF)
  57. # else
  58.    int rt_fatal_po(char *,struct _func_frame *);
  59.    int rt_fatal_p2_o(char *,char *,struct _func_frame *);
  60. #  define FATAL(msg)     rt_fatal_po(msg,&FF)
  61. #  define FATAL2(msg,str) rt_fatal_2_po(msg,str,&FF)
  62. # endif
  63. #else
  64. # ifdef DEBUG
  65. #  define FATAL(msg)     rt_fatal(__FILE__,__LINE__,msg)
  66. #  define FATAL2(msg,str) rt_fatal_2(__FILE__,__LINE__,msg,str)
  67. # else
  68. #  define FATAL(msg)     rt_fatal2(msg)
  69. #  define FATAL2(msg,str) rt_fatal2_2(msg,str)
  70. # endif
  71. #endif
  72.  
  73. #define SAMIN(x,y)       (((x)<(y))?(x):(y))
  74.  
  75. #define CHKERR(x,msg,y) (((x)?FATAL(msg):0),(y))
  76. #define CHKOK(x,msg,y)      (((!(x))?FATAL(msg):0),(y))
  77.  
  78. #define DESTROYED(x)   ((OB)x)->header.destroyed
  79. #define DESTROY(x)     ((OB)x)->header.destroyed=1
  80. #define VOID(x)        (x)==NULL
  81.  
  82. #ifdef BOUNDS_CHK
  83. # define CHK_BOUNDS(v,low,high,expr) CHKERR(((v)<(low)||(v)>(high)),"Out of bounds",expr)
  84. #else
  85. # define CHK_BOUNDS(v,low,high,expr) (expr)
  86. #endif
  87.  
  88. #ifdef DESTROY_CHK
  89. # if defined(VOID_CHK) && !defined(NULL_SEGFAULTS)
  90. #  define CHK(x,y) CHKERR(VOID(x),"Access to void",CHKERR(DESTROYED(x),"Access to destroyed object",(y)))
  91. # else
  92. #  define CHK(x,y) CHKERR(DESTROYED(x),"Access to destroyed object",(y))
  93. # endif
  94. #else
  95. # if defined(VOID_CHK) && !defined(NULL_SEGFAULTS)
  96. #  define CHK(x,y) CHKERR(VOID(x),"Access to void",(y))
  97. # else
  98. #  define CHK(x,y) y
  99. # endif
  100. #endif
  101.  
  102. /* Macros for FLT and FLTD */
  103.  
  104. /* We could check for division by zero here, but IEEE says to
  105.  * return NaN, and we don't handle any other IEEE traps so to
  106.  * be consistent just ignore it here.
  107. */
  108. #define FLTDIV(x,y)    (x/y)
  109. #define FLTDDIV(x,y)   (x/y)
  110.  
  111. #ifndef ARITH_CHK 
  112. # define FLTINT(x)      (INT)x
  113. # define FLTDINT(x)     (INT)x
  114. #else
  115. # define FLTINT(x)      CHKERR(((INT)x)!=x,"Not an integer",(INT)x)
  116. # define FLTDINT(x)     CHKERR(((INT)x)!=x,"Not an integer",(INT)x)
  117. #endif
  118.  
  119. #define FLTASET(f,b,v)  CHK_BOUNDS(b,0,31,rt_fltaset(f,b,v))
  120. #define FLTAGET(f,b)    CHK_BOUNDS(b,0,31,rt_fltaget(f,b))
  121. #define FLTDASET(f,b,v) CHK_BOUNDS(b,0,63,rt_fltdaset(f,b,v))
  122. #define FLTDAGET(f,b)   CHK_BOUNDS(b,0,63,rt_fltdaget(f,b))
  123.  
  124. #define FLTSTORE(f,s)  (sprintf((s)->arr_part,"%g",f),strlen((s)->arr_part))
  125. #define FLTSTOREPREC(f,p,s) (sprintf((s)->arr_part,"%.*g",p,f),strlen((s)->arr_part))
  126. #define FLTDSTORE(f,s)  (sprintf((s)->arr_part,"%g",f),strlen((s)->arr_part))
  127. #define FLTDSTOREPREC(f,p,s) (sprintf((s)->arr_part,"%.*lg",p,f),strlen((s)->arr_part))
  128.  
  129. #if !defined(FLT_MAX) || !defined(MINFLOAT)
  130. # define FLTMAXNORMAL     r_max_normal()
  131. # define FLTMINNORMAL     r_min_normal()
  132. # define FLTMAXSUBNORMAL  r_max_subnormal()
  133. # define FLTMINSUBNORMAL  r_min_subnormal()
  134. # define FLTDMAXNORMAL    max_normal()
  135. # define FLTDMINNORMAL    min_normal()
  136. # define FLTDMAXSUBNORMAL max_subnormal()
  137. # define FLTDMINSUBNORMAL min_subnormal()
  138. #else
  139. # define FLTMAXNORMAL     FLT_MAX
  140. # define FLTMINORMAL      FLT_MIN
  141. # define FLTMAXSUBNORMAL  MAXFLOAT /* Is this right? */
  142. # define FLTMINSUBNORMAL  MINFLOAT
  143. # define FLTDMAXNORMAL    DBL_MAX
  144. # define FLTDMINORMAL     DBL_MIN
  145. # define FLTDMAXSUBNORMAL MAXDOUBLE /* Is this right? */
  146. # define FLTDMINSUBNORMAL MINDOUBLE
  147. #endif
  148.  
  149. /* 4.1 AIX native C compiler does not allow to return qualified const types.
  150.    Oddly enough, 3.2 AIX compiler does not mind */
  151. /* This is also true for ULTRIX */
  152. #if (defined(_AIX41) || defined(ultrix)) && !defined(__GNUC__) || defined(__alpha)
  153. # define RETURNED_CONST
  154. #else
  155. # define RETURNED_CONST const
  156. #endif
  157.  
  158. #ifdef linux
  159. # define FLTDEXP10(f)    pow10(f)
  160. #define iszero(f) ((f)==0.0)
  161. static int ilogb(double f) { int i; frexp(f,&i); return i-1; }
  162. #define isnormal(f) ((int)1)  /* these two are hacks esc*/
  163. #define issubnormal(f) ((int)0)
  164.  
  165. #elif defined(_AIX) || defined(SUNOS5) || defined(__NeXT__) || defined(__sgi) || defined(ALPHA) || defined(__hpux) || defined(__FreeBSD__) || defined(__alpha)
  166. # define FLTDEXP10(f)    pow(10.0,f)
  167. #else
  168. # define FLTDEXP10(f)    exp10(f)
  169. #endif
  170.  
  171.  
  172. /* This is from stoehr@informatik.tu-muenchen.de */
  173. #if defined(__hpux) || defined(linux) || defined(__NEXT__)
  174. # define cbrt(v) pow(v,(1.0/3.0))
  175. double scalbn(double, int);
  176. #endif
  177.  
  178. #if defined(SUNOS5) || defined(__hpux) || defined(__FreeBSD__) || defined(__sgi) || defined(linux) || defined(__alpha)
  179. double signaling_nan(int sig);
  180. double infinity();
  181. #endif
  182.  
  183. /* Put other machines which define "aint" here (round to zero).  I
  184.  * don't know why this function isn't defined on most platforms.  AIX
  185.  * calls it "trunc".  "ceil" and "floor" _should_ be defined
  186.  * everywhere, we hope.  Some platforms appear to support the float
  187.  * version truncf (or ftrunc), but don't document it (bastards), so we
  188.  * won't rely on it.  
  189. */
  190. #if defined(SUNOS4)
  191. # define FLTDTRUNCATE(x) aint(x)
  192. # define FLTTRUNCATE(x) ((FLT)aint((FLTD)x))
  193. #elif defined(_AIX) || defined(__sgi)
  194. # define FLTDTRUNCATE(x) trunc(x)
  195. # define FLTTRUNCATE(x) ((FLT)trunc((FLTD)x))
  196. #else
  197. # define FLTDTRUNCATE(x) ( ((x)<0.0)?ceil(x):floor(x) )
  198. # define FLTTRUNCATE(x) (FLT)FLTDTRUNCATE((FLTD)x)
  199. #endif
  200.  
  201. #if defined(__hpux) || defined(SCO) || defined(WIN32) || defined(__riscos__)
  202. /* This is just a quick hack - real rounding does something better
  203.  * for rounding - somebody send me a correct version. 
  204.  * Should be doing IEEE round to even.
  205. */
  206. # define FLTDROUND(x)    (fabs(x-floor(x))<0.5)?floor(x):(floor(x)+1)
  207. #else
  208. # define FLTDROUND(x)    rint(x)
  209. #endif
  210. #define FLTROUND(x)      (FLT)(FLTDROUND((FLTD)(x)))
  211.  
  212. /* IN */
  213. #define INGETSTRSIZED(s,sz) CHK_BOUNDS(sz-1,0,s->loc,fgets((s)->arr_part,sz,stdin))
  214.  
  215. /* INT */
  216.  
  217. /* Some of these rely on common subexpression elimination in the C 
  218.  * compiler to allow them to conveniently be macros.  But then, this
  219.  * is the '90s.
  220.  * INTDIV and INTMOD may not be right for all machines/compilers.
  221.  * Someone should take the time to scope out the right set of #ifdefs
  222.  * for this.
  223. */
  224.  
  225. #ifndef ARITH_CHK
  226.  
  227. # define INTPLUS(x,y)    x+y
  228. # define INTMINUS(x,y)   x-y
  229. # define INTTIMES(x,y)   x*y
  230. # define INTDIV(x,y)     (x<0&&x!=(x/y)*y)?(x/y)-1:(x/y)
  231. # define INTMOD(x,y)     ((x%y)<0)?(x%y)+y:(x%y)
  232. /* The following version was introduced by David, 
  233.  * but yields different results when x<0. This breaks
  234.  * the INTI class 
  235.  * # define INTDIV(x,y)     (x>=0||x%y?x/y:y>0?x/y-1:x/y+1)
  236.  * # define INTMOD(x,y)     (x%y>=0?x%y:y<0?x%y-y:x%y+y)
  237.  */
  238. # define INTUPLUS(x,y)   ((unsigned)x)+((unsigned)y)
  239. # define INTUMINUS(x,y)  ((unsigned)x)-((unsigned)y)
  240. # define INTUTIMES(x,y)  ((unsigned)x)*((unsigned)y)
  241. # define INTUDIV(x,y)    ((unsigned)x)/((unsigned)y)
  242. # define INTUMOD(x,y)    ((unsigned)x)%((unsigned)y)
  243. # define INTFLT(x)       (FLT)x
  244. # define INTFLTD(x)      (FLTD)x
  245. # define INTRSHIFT(x,s)  (x<0)?x>>s:(~((~x)>>s))
  246.  
  247. #else
  248.  
  249. /* This is a VERY SLOW way of doing arithmetic checking, because
  250.  * it doesn't take advantage of the overflow bits available on almost
  251.  * any platform, but which aren't accessible from C.  It would be a
  252.  * Good Thing to have special cases to exploit, for example, gcc's
  253.  * "asm" extension.  If you feel arithmetic checking is too slow,
  254.  * then please contribute a special case for your platform!
  255. */
  256.  
  257. #define INTPLUS(x,y)    CHKOK(((y>=0&&x<=(SINT_MAX-y))||(y<0&&x>=((signed)(((unsigned)SINT_MIN)-y)))),"Integer overflow on plus",x+y)
  258. #define INTMINUS(x,y)   CHKOK(((y>=0&&x>=(SINT_MIN+y))||(y<0&&x<=((signed)(((unsigned)SINT_MAX)+y)))),"Integer overflow on minus",x-y)
  259. #define INTTIMES(x,y)   CHKOK(((x==0)||(y==0)||(x>0&&y>0&&y<=SINT_MAX/x)||(x>0&&y<0&&y>=SINT_MIN/x)||(x<0&&y>0&&x>=SINT_MIN/y)||(x<0&&y<0&&x!=SINT_MIN&&y!=SINT_MIN&&-x<=SINT_MAX/(-y))),"Integer overflow on times",x*y)
  260. #define INTDIV(x,y)     CHKOK(y!=0,"Division by zero",((x<0&&x!=(x/y)*y)?(x/y)-1:(x/y)))
  261. #define INTMOD(x,y)     CHKOK(y!=0,"Mod by zero",((x%y)<0)?(x%y)+y:(x%y))
  262. /* See comments about INTDIV above
  263.  * #define INTDIV(x,y)     CHKOK(y!=0,"Division by zero",(x>=0||x%y?x/y:y>0?x/y-1:x/y+1))
  264.  * #define INTMOD(x,y)     CHKOK(y!=0,"Mod by zero",(x%y>=0?x%y:y<0?x%y-y:x%y+y))
  265.  */
  266. #define INTUPLUS(x,y)   CHKOK(x<=(SUINT_MAX-y),"Integer overflow on unsigned plus",((unsigned)x)+((unsigned)y))
  267. #define INTUMINUS(x,y)  CHKOK(y<=x,"Integer overflow on unsigned minus",((unsigned)x)-((unsigned)y))
  268. #define INTUTIMES(x,y)  CHKOK((x==0)||(y<=SUINT_MAX/x),"Integer overflow on unsigned times",((unsigned)x)*((unsigned)y))
  269. #define INTUDIV(x,y)    CHKOK(y!=0,"Integer unsigned division by zero",((unsigned)x)/((unsigned)y))
  270. #define INTUMOD(x,y)    CHKOK(y!=0,"Integer unsigned mod by zero",((unsigned)x)%((unsigned)y))
  271. #define INTFLT(x)       CHKOK(((INT)((FLT)x))==x,"Integer would overflow conversion to FLT",(FLT)x)
  272. #define INTFLTD(x)      CHKOK(((INT)((FLTD)x))==x,"Integer would overflow conversion to FLTD",(FLTD)x)
  273. #define INTRSHIFT(x,s)  (x<0)?x>>s:(~((~x)>>s))
  274.  
  275. #endif
  276.  
  277. /* SYS */
  278.  
  279. #ifndef DESTROY_CHK 
  280.  
  281. # define SYSDESTROY(x)   ZFREE(x)
  282. # define ATTR(x,y)       (x)->y
  283. # define ATTRs(x,y,n)    ((x)==NULL?(n):((x)->y))
  284. # define SATTR(x,y,z)    (x)->y=z
  285. # define TAG(x)          ((OB)x)->header.tag
  286. # define ASIZE(x)        (x)->asize
  287. # define VASIZE(x)       (x ## _asize) /* for value types, x must be the type */
  288. # define ARR(x,y)        CHK_BOUNDS(y,0,ASIZE(x)-1,(x)->arr_part[y])
  289. # define VARR(T,x,y)     CHK_BOUNDS(y,0,VASIZE(T)-1,(x).arr_part[y])
  290. # define SARR(x,y,z)     CHK_BOUNDS(y,0,ASIZE(x)-1,(x)->arr_part[y]=z)
  291. # define VSARR(T,x,y,z)  CHK_BOUNDS(y,0,VASIZE(T)-1,(x).arr_part[y]=z)
  292.  
  293. #else
  294.  
  295. # ifdef NULL_SEGFAULTS
  296. /* if accesses of NULL pointers are guaranteed to segfault, we can
  297.  * avoid generating code in-line to check for this.
  298. */
  299. #  define SYSDESTROY(x)   CHKERR(DESTROYED(x),"Tried to destroy already destroyed object",DESTROY(x))
  300. #  define ATTR(x,y)       CHKERR(DESTROYED(x),"Attr access of destroyed object",x->y)
  301. #  define ATTRs(x,y,n)      ((x)==NULL?(n):((x)->y))
  302. #  define SATTR(x,y,z)    CHKERR(DESTROYED(x),"Attr write access of destroyed object",x->y=z)
  303. #  define TAG(x)          CHKERR(DESTROYED(x),"Tag access of destroyed object",((OB)x)->header.tag)
  304. #  define ASIZE(x)        CHKERR(DESTROYED(x),"Asize access of destroyed object",(x)->asize)
  305. #  define VASIZE(x)       (x ## _asize) /* for value types, x must be the type */
  306. #  define ARR(x,y)        CHKERR(DESTROYED(x),"Array access of destroyed object",CHK_BOUNDS(y,0,ASIZE(x)-1,(x)->arr_part[y]))
  307. #  define VARR(T,x,y)     CHK_BOUNDS(y,0,VASIZE(T)-1,(x).arr_part[y])
  308. #  define SARR(x,y,z)     CHKERR(DESTROYED(x),"Array write access of destroyed object",CHK_BOUNDS(y,0,ASIZE(x)-1,(x)->arr_part[y]=z))
  309. #  define VSARR(T,x,y,z)  CHK_BOUNDS(y,0,VASIZE(T)-1,(x).arr_part[y]=z)
  310.  
  311. # else
  312.  
  313. #  define SYSDESTROY(x)   CHKERR(VOID(x),"Tried to destroy void",CHKERR(DESTROYED(x),"Tried to destroy already destroyed object",DESTROY(x)))
  314. #  define ATTR(x,y)       CHKERR(VOID(x),"Attr access of void",CHKERR(DESTROYED(x),"Attr access of destroyed object",((x)->y)))
  315. #  define ATTRs(x,y,n)    ((x)==NULL?(n):((x)->y))
  316. #  define SATTR(x,y,z)    CHKERR(VOID(x),"Attr write access of void",CHKERR(DESTROYED(x),"Attr write access of destroyed object",x->y=z))
  317. #  define TAG(x)          CHKERR(VOID(x),"Tag access of void",CHKERR(DESTROYED(x),"Tag access of destroyed object",((OB)x)->header.tag))
  318. #  define ASIZE(x)        CHKERR(VOID(x),"Asize access of void",CHKERR(DESTROYED(x),"Asize access of destroyed object",(x)->asize))
  319. #  define VASIZE(x)       (x ## _asize) /* for value types, x must be the type */
  320. #  define ARR(x,y)        CHKERR(VOID(x),"Array access of void",CHKERR(DESTROYED(x),"Array access of destroyed object",CHK_BOUNDS(y,0,ASIZE(x)-1,(x)->arr_part[y])))
  321. #  define VARR(T,x,y)     CHK_BOUNDS(y,0,VASIZE(T)-1,(x).arr_part[y])
  322. #  define SARR(x,y,z)     CHKERR(VOID(x),"Array write access of void",CHKERR(DESTROYED(x),"Array write access of destroyed object",CHK_BOUNDS(y,0,ASIZE(x)-1,(x)->arr_part[y]=z)))
  323. #  define VSARR(T,x,y,z)  CHK_BOUNDS(y,0,VASIZE(T)-1,(x).arr_part[y]=z)
  324.  
  325. # endif
  326. #endif
  327.  
  328. /*
  329.  * define some macros used in pSather, which are also used in Sather
  330.  * (for compatibility reasons)
  331.  */
  332. #ifndef PSATHER
  333. #define READTAG(t,obj)    ((t)=TAG(obj))
  334. #endif
  335.  
  336.  
  337. #ifdef DETERMINISTIC
  338. # define SYSID(x)        CHK(x,CHKOK(((OB)x)->header.tag>=0,"Called SYS::id on value type",((OB)x)->header.id))
  339. #else
  340. /* Chop off bits from right side.  The exect number depends on whether the
  341.  * allocator aligns things strongly.  If this isn't true, then
  342.  * a smaller number of bits (like 2) might be more appropriate.
  343. */
  344. # define SYSID(x)        CHK(x,CHKOK(((OB)x)->header.tag>=0,"Called SYS::id on value type",(INT)(((unsigned long)x)>>3)))
  345. #endif
  346.  
  347. #define SYSTP(x)        TAG(x)
  348. #define SYSSTRFORTP(x)  gen_SYS_str_for_tp(x)
  349. #define SYSOBEQ(x,y)    (x==y)||(x!=NULL)&&(y!=NULL)&&(((OB)x)->header.tag==((OB)y)->header.tag)&&gen_SYS_ob_eq((OB)x,(OB)y)
  350. #define SYSEXTOBFOR(x)  (void*)x 
  351.  
  352. /* CHAR */
  353.  
  354. #define CHARAGET(c,b)   CHK_BOUNDS(b,0,7,(CHAR)((c&(1<<b))!=0))
  355. #define CHARASET(c,b,v) CHK_BOUNDS(b,0,7,(CHAR)((c&(~(1<<b)))|(v<<b)))
  356.  
  357. /* FSTR */
  358.  
  359. #define FSTRASET(f,i,c) CHK(f,CHK_BOUNDS(i,0,f->loc-1,(f)->arr_part[i]=c))
  360. #define FSTRAGET(f,i)   CHK(f,CHK_BOUNDS(i,0,f->loc-1,(f)->arr_part[i]))
  361. #define FSTRACOPY(f,s)  CHK(s,CHK(f,CHK_BOUNDS(ASIZE(s),0,ASIZE(f),(memcpy((f)->arr_part,(s)->arr_part,ASIZE(s))))))
  362. #define FSTRACOPYF(f,f2) CHK(f2,CHK(f,CHK_BOUNDS(f2->loc,0,ASIZE(f),(memcpy((f)->arr_part,(f2)->arr_part,f2->loc)))))
  363. #define FSTRACOPYN(f,s,n) CHK(s,CHK(f,CHK_BOUNDS(n,0,ASIZE(f),CHK_BOUNDS(n,0,ASIZE(s),(memcpy((f)->arr_part,(s)->arr_part,n))))))
  364. #define FSTRACOPYNF(f,f2,n) CHK(f2,CHK(f,CHK_BOUNDS(n,0,ASIZE(f),CHK_BOUNDS(n,0,f2->loc,(memcpy((f)->arr_part,(f2)->arr_part,n))))))
  365. #define FSTRACOPYIS(f,i,s) CHK(s,CHK(f,CHK_BOUNDS(i,0,ASIZE(f)-1,memcpy((f)->arr_part+i,(s)->arr_part,SAMIN(ASIZE(f)-i,ASIZE(s))))))
  366. #define FSTRACOPYIF(f,i,f2) CHK(f2,CHK(f,CHK_BOUNDS(i,0,ASIZE(f)-1,memcpy((f)->arr_part+i,(f2)->arr_part,SAMIN(ASIZE(f)-i,f2->loc)))))
  367.  
  368. /* STR */
  369.  
  370. #define STRAGET(s,i)    CHK(s,CHK_BOUNDS(i,0,ASIZE(s)-1,(s)->arr_part[i]))
  371. #define STRACOPYNF(s,f,n) CHK(s,CHK(f,CHK_BOUNDS(n,0,ASIZE(s),CHK_BOUNDS(n,0,f->loc,memcpy((s)->arr_part,(f)->arr_part,n)))))
  372. #define STRACOPYN(s,s2,n) CHK(s,CHK(s2,CHK_BOUNDS(n,0,ASIZE(s),CHK_BOUNDS(n,0,ASIZE(s2),memcpy((s)->arr_part,(s2)->arr_part,n)))))
  373. #define STRACOPYIS(s,i,s2) CHK(s2,CHK(s,CHKOK((ASIZE(s2)==0)||((i>=0)&&(i<ASIZE(s))),"Bad precondition for STR::acopy",memcpy((s)->arr_part+i,(s2)->arr_part,SAMIN(ASIZE(s)-i,ASIZE(s2))))))
  374. #define STRISEQHELPER(s,s2,len) (memcmp((s)->arr_part,(s2)->arr_part,len)==0)
  375.  
  376. /* AREF */
  377. #define AREFACOPY(s,f)   CHK(s,CHK(f,memcpy((s)->arr_part,(f)->arr_part,sizeof((s)->arr_part[0])*SAMIN(ASIZE(s),ASIZE(f)))))
  378. #define AREFACOPYB(s,b,f) CHK(s,CHK(f,CHK_BOUNDS(b,0,ASIZE(s),memcpy((s)->arr_part+b,(f)->arr_part,sizeof((s)->arr_part[0])*SAMIN(ASIZE(s)-b,ASIZE(f))))))
  379. #define AREFACOPYBN(s,b,n,f) CHK(s,CHK(f,CHK_BOUNDS(b,0,ASIZE(s),CHK_BOUNDS(b+n,0,ASIZE(s),CHK_BOUNDS(n,0,ASIZE(f),memcpy((s)->arr_part+b,(f)->arr_part,sizeof((s)->arr_part[0])*n))))))
  380. #define AREFACOPYBNS(s,b,n,sr,f) CHK(s,CHK(f,CHK_BOUNDS(b,0,ASIZE(s),CHK_BOUNDS(b+n,0,ASIZE(s),CHK_BOUNDS(sr,0,ASIZE(f),CHK_BOUNDS(n+sr,0,ASIZE(f),memcpy((s)->arr_part+b,(f)->arr_part+sr,sizeof((s)->arr_part[0])*n)))))))
  381. #define AREFACLEAR(s)    CHK(s,memset((s)->arr_part,0,sizeof((s)->arr_part[0])*ASIZE(s)))
  382.  
  383. /* AVAL */
  384. #define AVALACOPY(T,s,f)   CHK(s,CHK(f,memcpy(s.arr_part,f.arr_part,sizeof(s.arr_part[0])*VASIZE(T))))
  385. #define AVALACOPYB(T,s,b,f) CHK(s,CHK(f,CHK_BOUNDS(b,0,VASIZE(T),memcpy(s.arr_part+b,f.arr_part,sizeof(s.arr_part[0])*VASIZE(T)-b))))
  386. #define AVALACOPYBN(T,s,b,n,f) CHK(s,CHK(f,CHK_BOUNDS(b,0,VASIZE(T),CHK_BOUNDS(b+n,0,VASIZE(T),CHK_BOUNDS(n,0,VASIZE(T),,memcpy(s.arr_part+b,f.arr_part,sizeof(s.arr_part[0])*n))))))
  387. #define AVALACOPYBNS(T,s,b,n,sr,f) CHK(s,CHK(f,CHK_BOUNDS(b,0,VASIZE(T),CHK_BOUNDS(b+n,0,VASIZE(T),CHK_BOUNDS(sr,0,VASIZE(T),CHK_BOUNDS(n+sr,0,VASIZE(T),memcpy(s.arr_part+b,f.arr_part+sr,sizeof(s.arr_part[0])*n)))))))
  388.  
  389. /* pSather things */
  390.